/*
 * BehaviorProvider.java
 *
 * Created on November 29, 2007, 1:23 PM
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */

package com.servoy.plugins;

import com.servoy.j2db.server.headlessclient.dataui.WebEventExecutor;
import com.servoy.j2db.util.Utils;

import org.apache.wicket.RequestCycle;
import org.apache.wicket.ajax.AbstractDefaultAjaxBehavior;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.mozilla.javascript.Function;
import org.mozilla.javascript.Context;
import org.mozilla.javascript.JavaScriptException;
import java.util.Hashtable;
/**
 *
 * @author Sean
 */
public class BehaviorProvider extends AbstractDefaultAjaxBehavior {
    
	private static final long serialVersionUID = 7666601280436256255L;

    private Hashtable callbacks = new Hashtable();
    private String paramString;

    public CharSequence getCallbackUrl(boolean b){
        String url = super.getCallbackUrl(b).toString();
        if(paramString != null){
            url += paramString;
        }
        return url;
    }
    
    protected void respond(AjaxRequestTarget target){   
        String param = RequestCycle.get().getRequest().getParameter("m");  
        if(param != null){
            String[] args = param.split(":");
            int mhash = Utils.getAsInteger(args[0]);
            Function f = (Function)callbacks.get(new Integer(mhash));
            if(f != null){

                //  call back
                String[] func_args = new String[args.length - 1];
                for(int i = 1; i < args.length; i++)
                    func_args[i-1] = args[i];
                processCallback(f, func_args);
                
                //	update client state
                WebEventExecutor.generateResponse(target, target.getPage());
                
            } else {
            	throw new RuntimeException("Could not find function!");
            }
        }
    }
    
    public String getUrlForCallback(Object callback, String[] args){
        paramString = "&m=" + callback.hashCode();
        if(args != null){
            for(int i = 0; i < args.length; i++){
                paramString += ":'+"+args[i]+"+'";
            }
        }
        String script = getCallbackScript(true).toString();        
        return script;
    }
    
    public void addCallBack(Function function){
        callbacks.put(new Integer(function.hashCode()), function);
    }
    
    private void processCallback(final Function function, final Object[] args){

        Context context = Context.enter();
        try {
    
            function.call(context, function.getParentScope(), function.getParentScope(), args);
            
        } catch (JavaScriptException e) {
            throw new RuntimeException("Java Script Exception", e);
        } finally {
            Context.exit();
        }
    }
    
    protected CharSequence getPreconditionScript(){
    	return "return true;";
    }
}
